/**
 * @function 判断数据的类型
 * @param {object} prop 需要判断类型的参数
 * @returns {string}
 * @version 1.0
 * @author 小明
 */
export function getObjType(prop) {
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object',
  }
  return map[Object.prototype.toString.call(prop)]
}

/**
 * @function 对象深度克隆
 * @param {any} data 要克隆的参数
 * @returns {any}
 */
export function deepClone(data) {
  var type = getObjType(data)
  var obj
  if (type === 'array') {
    obj = []
  } else if (type === 'object') {
    obj = {}
  } else {
    // 不再具有下一层次
    return data
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]))
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key])
    }
  }
  return obj
}

class newData extends Date {
  /**
   * 格式转换
   * @param day 日期格式 YYYY-MM-DD hh:mm:ss 大写HH是12小时制，小写hh是24小时
   * @returns 
   */
  format(day = 'YYYY-MM-DD'){
    const date = this
		let y = date.getFullYear();
		let MM = date.getMonth() + 1;
		MM = MM < 10 ? "0" + MM : MM;
		let d = date.getDate();
		d = d < 10 ? "0" + d : d;
		let h = date.getHours();
		h = h < 10 ? "0" + h : h;
		let h12 = h > 12 ? h - 12 : Number(h);
		h12 = h12 < 10 ? "0" + h12 : h12;
		let m = date.getMinutes();
		m = m < 10 ? "0" + m : m;
		let s = date.getSeconds();
		s = s < 10 ? "0" + s : s;
		const str = day.replace('YYYY', y).replace('MM', MM).replace('DD', d).replace('HH', h).replace('hh', h12).replace('mm', m).replace('ss',s)
			.replace('ss', s)
		return str
  }
}
/**
 * 日期格式转换
 * @param value date
 * @returns 
 */
export function moment(value) {
	if (typeof value === 'string' && !isNaN(value)) value = Number(value)
	let date = value ? new newData(value) : new newData();
	return date
}

const easeInOutQuad = (t, b, c, d) => {
  t /= d / 2;
  if (t < 1) {
    return (c / 2) * t * t + b;
  }
  t--;
  return (-c / 2) * (t * (t - 2) - 1) + b;
};

// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
const requestAnimFrame = (function () {
  return (
    window.requestAnimationFrame ||
    (window ).webkitRequestAnimationFrame ||
    (window ).mozRequestAnimationFrame ||
    function (callback) {
      window.setTimeout(callback, 1000 / 60);
    }
  );
})();

/**
 * Because it's so fucking difficult to detect the scrolling element, just move them all
 * @param {number} amount
 */
const move = (amount) => {
  document.documentElement.scrollTop = amount;
  (document.body.parentNode ).scrollTop = amount;
  document.body.scrollTop = amount;
};

const position = () => {
  return (
    document.documentElement.scrollTop ||
    (document.body.parentNode ).scrollTop ||
    document.body.scrollTop
  );
};

/**
 * @param {number} to
 * @param {number} duration
 * @param {Function} callback
 */
export const scrollTo = (to, duration, callback) => {
  const start = position();
  const change = to - start;
  const increment = 20;
  let currentTime = 0;
  duration = typeof duration === 'undefined' ? 500 : duration;
  const animateScroll = function () {
    // increment the time
    currentTime += increment;
    // find the value with the quadratic in-out easing function
    const val = easeInOutQuad(currentTime, start, change, duration);
    // move the document.body
    move(val);
    // do the animation unless its over
    if (currentTime < duration) {
      requestAnimFrame(animateScroll);
    } else {
      if (callback && typeof callback === 'function') {
        // the animation is done so lets callback
        callback();
      }
    }
  };
  animateScroll();
};
